package com.kanas.webak.rbac.controller;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.kanas.app.web.security.SpringSecurityUtils;
import com.kanas.framework.business.BusinessHandler;
import com.kanas.framework.business.ResponseMessage;
import com.kanas.framework.support.ControllerSupport;
import com.kanas.framework.system.FunctionGroup;
import com.kanas.framework.system.Module;
import com.kanas.framework.web.context.WebAppContext;
import com.kanas.webak.admin.domain.AppUser;
import com.kanas.webak.admin.service.UserService;
import com.kanas.webak.organization.domain.Organization;
import com.kanas.webak.organization.service.OrganizationService;
import com.kanas.webak.rbac.domain.AppPermission;
import com.kanas.webak.rbac.domain.AppRole;
import com.kanas.webak.rbac.domain.AppUserRole;
import com.kanas.webak.rbac.service.AppRoleService;
import com.transino.bop.datasource.SqlExecutorService;

@Controller
@RequestMapping("/app/rbac/role")
public class SysRoleController extends ControllerSupport {
	private AppRoleService appRoleService;
	private UserService userService;
	private OrganizationService orgService;
	private SqlExecutorService sqlExecutorService;
	
	@RequestMapping(value="", method=RequestMethod.GET)
	public ModelAndView role(final HttpServletRequest request){
		ModelAndView mv=new ModelAndView();
		mv.setViewName("modules/sysadmin/rbac_role");
		List<FunctionGroup> fgs = new ArrayList<FunctionGroup>();
		List<Module> modules = ((WebAppContext)request.getSession().getServletContext().getAttribute(WebAppContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).listModules();
		if(modules!=null && modules.size()>0) {
			for(Module m:modules) {
				if(m.getGroups()!=null && m.getGroups().size()>0) {
					for(FunctionGroup fg:m.getGroups()) {
						loopFunctionGroup(fgs,fg);
					}
				}
			}
		}
		mv.addObject("groups", fgs);
		List<Organization> orgs = orgService.findAll();
		mv.addObject("orgs", orgs);
		return mv;
	}
	public List<FunctionGroup> loopFunctionGroup(List<FunctionGroup> fgs,FunctionGroup fg) {
		fgs.add(fg);
		if(fg.getGroups()!=null && fg.getGroups().size()>0) {
			for(FunctionGroup g:fg.getGroups()) {
				loopFunctionGroup(fgs,g);
			}
		}
		return fgs;
	}
	
	@RequestMapping(value="/{type}/list",method=RequestMethod.GET)
	public ModelAndView list(@PathVariable("type") final String type){
		ModelAndView mv=new ModelAndView();
		mv.setViewName("modules/sysadmin/rbac_role_list");
		mv.addObject("roleList", appRoleService.findRoles(type));
		return mv;
	}
	
	@RequestMapping(value="/list.json",method=RequestMethod.GET)
	public @ResponseBody Map<String,Object> listAll(){
		Map<String,Object> response=new HashMap<String,Object>();
		response.put("identifier", "id");
		response.put("label", "label");
		response.put("items", appRoleService.findAll());
		return response;
	}
	
	@RequestMapping(value="/export.json",method=RequestMethod.GET)
	public @ResponseBody Map<String,Object> export(@RequestParam(value="id",required=false) final String id,
			@RequestParam(value="orgid",required=false) final String orgId){
		Map<String,Object> response=new HashMap<String,Object>();
		List<AppRole> ars = new ArrayList<AppRole>();
		List<AppRole> exports = appRoleService.findByExportFlagAndEnableFlag(true, true);
		List<AppRole> aus = userService.findRoles(id, orgId);
		for(AppRole ex:exports) {
			if(!aus.contains(ex)) {
				ars.add(ex);
			}
		}
		response.put("identifier", "id");
		response.put("label", "label");
		response.put("items", ars);
		return response;
	}
	
	@RequestMapping(value="/include.json",method=RequestMethod.GET)
	public @ResponseBody Map<String,Object> include(@RequestParam(value="id",required=false) final String id){
		Map<String,Object> response=new HashMap<String,Object>();
		List<AppRole> ars = new ArrayList<AppRole>();
		if(id!=null && !id.equals("")) {
			ars = appRoleService.inclusionRole(id);
			for(AppRole ar:ars) {
				ar.setChecked(true);
			}
		}
		response.put("identifier", "id");
		response.put("label", "label");
		response.put("items", ars);
		return response;
	}
	
	@RequestMapping(value="/inclusion.json",method=RequestMethod.GET)
	public @ResponseBody Map<String,Object> inclusion(@RequestParam(value="id",required=false) final String id){
		Map<String,Object> response=new HashMap<String,Object>();
		List<AppRole> ars = new ArrayList<AppRole>();
		List<AppRole> checkedARS = new ArrayList<AppRole>();
		List<AppRole> uncheckARS = new ArrayList<AppRole>();
		if(id!=null && !id.equals("")) {
			ars = appRoleService.findByExportFlagAndEnableFlag(false, true);
			checkedARS.addAll(appRoleService.inclusionRole(id));
		}
		if(checkedARS!=null && checkedARS.size()>0) {
			for(AppRole ar:ars) {
				if(!checkedARS.contains(ar) && !ar.getId().equals(id)) {
					uncheckARS.add(ar);
				}
			}
			ars = uncheckARS;
		}
		response.put("identifier", "id");
		response.put("label", "label");
		response.put("items", ars);
		return response;
	}
	
	@RequestMapping(value="/userRole.json",method=RequestMethod.GET)
	public @ResponseBody Map<String,Object> userRole(@RequestParam(value="id",required=false) final String id) throws Exception{
		Map<String,Object> response=new HashMap<String,Object>();
		List<AppUserRole> aus = new ArrayList<AppUserRole>();
		if(id!=null && !id.equals("")) {
			aus = appRoleService.findUserRoles(id);
		}
		response.put("identifier", "id");
		response.put("label", "label");
		response.put("items", aus);
		return response;
	}
	
	@RequestMapping(value="/permission.json",method=RequestMethod.GET)
	public @ResponseBody Map<String,Object> permission(@RequestParam(value="id",required=false) final String id) throws Exception{
		Map<String,Object> response=new HashMap<String,Object>();
		List<AppPermission> aps = new ArrayList<AppPermission>();
		if(id!=null && !id.equals("")) {
			aps = appRoleService.findPermissions(id);
		}
		response.put("identifier", "id");
		response.put("label", "label");
		response.put("items", aps);
		return response;
	}
	
	@RequestMapping(value="/{rid}/operate", method=RequestMethod.POST)
	public @ResponseBody ResponseMessage operate(@PathVariable("rid") final String rid,
			@RequestParam(value="id",required=false) final String id,@RequestParam(value="flag",required=false) final boolean flag) {
		ResponseMessage response = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.operateInclusionRole(rid, id, flag);
			}
		}, logger);
		return response;
	}
	
	@RequestMapping(value="/new", method=RequestMethod.GET)
	public ModelAndView newUser(){
		ModelAndView mv=new ModelAndView();
		mv.setViewName("modules/sysadmin/rbac_role_new");
		return mv;
	}
	
	@RequestMapping(value="/new", method=RequestMethod.POST)
	public @ResponseBody ResponseMessage create(final AppRole role) {
		ResponseMessage response = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.addNew(role);
			}
		}, logger);
		return response;
	}
	
	@RequestMapping(value="/{rid}/edit", method=RequestMethod.GET)
	public ModelAndView editUser(@PathVariable("rid") final String rid){
		ModelAndView mv=new ModelAndView();
		mv.setViewName("modules/sysadmin/rbac_role_edit");
		AppRole role = appRoleService.findOne(rid);
		mv.addObject("role", role);
		return mv;
	}
	
	@RequestMapping(value="/{rid}/edit", method=RequestMethod.POST)
	public @ResponseBody ResponseMessage update(@PathVariable("rid") final String rid, final AppRole role) {
		ResponseMessage response = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.update(rid, role);
			}
		}, logger);
		return response;
	}
	
	@RequestMapping(value="/{roleId}",method=RequestMethod.DELETE)
	public @ResponseBody String deleteRole(@PathVariable("roleId") final String roleId, final HttpServletRequest request){
		ResponseMessage rm = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
//				String userId =SpringSecurityUtils.getPrincipalId(request).toString();
//				AppUser u = userService.findOne(userId);
				return appRoleService.delete(roleId);
			}
		}, logger);
		return rm.toString();
	}
	
	@RequestMapping(value="/user/{roleId}",method=RequestMethod.DELETE)
	public @ResponseBody String deleteFromUser(@PathVariable("roleId") final String roleId,final HttpServletRequest request){
		ResponseMessage rm = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				String userId =SpringSecurityUtils.getPrincipalId(request).toString();
				AppUser u=userService.findOne(userId);
				return userService.removeRole(u);
			}
		}, logger);
		return rm.toString();
	}
	
	@RequestMapping(value="/{roleId}/newPermission",method=RequestMethod.POST)
	public @ResponseBody String newPermission(@PathVariable("roleId") final String roleId,
			@RequestParam(value="id",required=false) final String pid){
		ResponseMessage rm = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.newPermission(roleId, pid);
			}
		}, logger);
		return rm.toString();
	}
	
	@RequestMapping(value="/permission/{pid}",method=RequestMethod.DELETE)
	public @ResponseBody String removePermission(@PathVariable("pid") final String pid){
		ResponseMessage rm = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.removePermission(pid);
			}
		}, logger);
		return rm.toString();
	}
	
	@RequestMapping(value="/userrole/{uid}",method=RequestMethod.DELETE)
	public @ResponseBody String removeUser(@PathVariable("uid") final String uid){
		ResponseMessage rm = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.removeUser(uid);
			}
		}, logger);
		return rm.toString();
	}
	
	@RequestMapping(value="/{roleId}/newuserrole",method=RequestMethod.POST)
	public @ResponseBody String newUserRole(@PathVariable("roleId") final String roleId,
			@RequestParam(value="orgId",required=false) final String orgId, @RequestParam(value="userId",required=false) final String userId){
		ResponseMessage rm = ResponseMessage.handleException(new BusinessHandler(){
			@Override
			public Object handle() throws Exception {
				return appRoleService.newUserRole(roleId, orgId, userId);
			}
		}, logger);
		return rm.toString();
	}
	
	//test
	@RequestMapping(value="/test", method=RequestMethod.GET)
	public ModelAndView test(final HttpServletRequest request) throws SQLException {
		
		ModelAndView mv = new ModelAndView();
		mv.setViewName("modules/sysadmin/test");
		Map<String,Object> testMap = new HashMap<String,Object>();
		testMap.put("username", "test");
//		String test = sqlExecutorService.executSqlGetJson("select * from kanas_user where username = :username", testMap, 0, 10);
//		testMap.put("id", "test");
//		testMap.put("username", "test2");
//		Integer testnum = sqlExecutorService.executSql("insert into kanas_user (id,username) values(:id,:username)",testMap);
		return mv;
	}

	public AppRoleService getAppRoleService() {
		return appRoleService;
	}
	
	@Resource(name="kanas.rbac0.service.sysroleservice")
	public void setAppRoleService(AppRoleService appRoleService) {
		this.appRoleService = appRoleService;
	}

	public UserService getUserService() {
		return userService;
	}
	
	@Resource(name="kanas.admin.service.sysuserservice")
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public OrganizationService getOrgService() {
		return orgService;
	}
	
	@Resource(name="kanas.admin.service.organization")
	public void setOrgService(OrganizationService orgService) {
		this.orgService = orgService;
	}
	
	public SqlExecutorService getSqlExecutorService() {
		return sqlExecutorService;
	}
	
	@Resource(name="kanas.data.service.sqlexecutor")
	public void setSqlExecutorService(SqlExecutorService sqlExecutorService) {
		this.sqlExecutorService = sqlExecutorService;
	}
	
}